home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / games / breaksrc.arc / break.asm
Assembly Source File  |  1988-10-09  |  9KB  |  283 lines

  1. ******************************************************************************
  2. *                                                                            *
  3. *    break.asm  version 1.0 of 20 August 1988   (C) L.J.M. de Wit 1988       *
  4. *                                                                            *
  5. * This software may be used and distributed freely if not used commercially  *
  6. * and the originator (me) is mentioned.                                      *
  7. *                                                                            *
  8. ******************************************************************************
  9.  
  10. * character codes
  11. tab      equ   9
  12. lf       equ   10
  13. cr       equ   13
  14.  
  15. * GEMDOS & (X)BIOS stuff
  16. gemdos   equ   1
  17. bios     equ   13
  18. xbios    equ   14
  19. ptermres equ   $31
  20. setexc   equ   5
  21. cconws   equ   9
  22. crawcin  equ   7
  23. super    equ   $20
  24. pterm0   equ   0
  25. pterm    equ   $4c
  26. iorec    equ   14
  27.  
  28. * divers
  29. bpaglen  equ   $100
  30. textlen  equ   12
  31. datalen  equ   20
  32. bsslen   equ   28
  33. intrupt  equ   -32        ; Code returned by interrupted programs
  34.  
  35. * iorec struct offsets; the buffer ptr. itself has offset 0
  36. ibufsize equ 4
  37. ibufhead equ 6
  38. ibuftl   equ 8
  39. ibuflow  equ 10
  40. ibufhi   equ 12
  41.  
  42.  
  43. brkinit:
  44.       move.l   4(sp),a0
  45.       adda.w   #$80,a0        ; a0 points to argument string start
  46.       moveq.l  #0,d0
  47.       move.b   (a0)+,d0        ; Get string length &
  48.       clr.b    (a0,d0.w)    ; ensure '\0' termination
  49. nxtbyt:
  50.       move.b   (a0)+,d0
  51.       beq      nxtdone        ; '\0' char is end of string
  52.       cmp.b    #'A',d0
  53.       blt.s    arge
  54.       cmp.b    #'Z',d0
  55.       bgt.s    arge
  56.       or.b     #$20,d0        ; Convert uppercase to lower
  57. arge:
  58.       cmp.b    #'e',d0        ; enable
  59.       bne.s    argd
  60.       st       enabled        ; enabled = TRUE
  61.       bra.s    nxtbyt
  62. argd:
  63.       cmp.b    #'d',d0        ; disable
  64.       bne.s    argi
  65.       sf       enabled        ; enabled = FALSE
  66.       bra.s    nxtbyt
  67. argi:
  68.       cmp.b    #'i',d0        ; input
  69.       bne.s    argc
  70.       move.l   a0,-(sp)
  71.       pea.l    inpmsg
  72.       move.w   #cconws,-(sp)
  73.       trap     #gemdos        ; Prompt for break char
  74.       addq.l   #6,sp
  75.       move.w   #crawcin,-(sp)
  76.       trap     #gemdos        ; Read the char
  77.       addq.l   #2,sp
  78.       move.l   d0,breakcode    ; and store it
  79.       pea.l    retmsg
  80.       move.w   #cconws,-(sp)
  81.       trap     #gemdos        ; Print a cr/lf
  82.       addq.l   #6,sp
  83.       move.l   (sp)+,a0
  84.       bra.s    nxtbyt
  85. argc:
  86.       cmp.b    #'c',d0        ; code of break char in hex
  87.       bne.s    argz
  88.       moveq.l  #0,d1        ; d1 will contain the code
  89. argcnxt:
  90.       move.b   (a0)+,d0
  91.       bne.s    argcnz        ; Not end of arg string yet
  92.       move.l   d1,breakcode    ; If end, store break char
  93.       bra      nxtdone        ; and goto end of arg string interpretation
  94. argcnz:
  95.       cmp.b    #' ',d0        ; End of number found
  96.       beq.s    argcend
  97.       cmp.b    #tab,d0        ; this one too
  98.       beq.s    argcend
  99.       cmp.b    #'0',d0        ; Now follows a series of tests and
  100.       blt.s    userr        ; conversions to find the hex digit's value.
  101.       cmp.b    #'a',d0
  102.       blt.s    argcnlc
  103.       sub.w    #32,d0        ; convert lower case to upper
  104. argcnlc:
  105.       cmp.b    #'F',d0
  106.       bgt.s    userr
  107.       cmp.b    #'9',d0
  108.       ble.s    argcnum
  109.       cmp.b    #'A',d0
  110.       blt.s    userr
  111.       subq.l   #7,d0        ; Make up for diff between '9' and 'A'
  112. argcnum:
  113.       sub.b    #'0',d0        ; '0' is the base: 0
  114.       asl.l    #4,d1        ; Multiply by 16
  115.       or.b     d0,d1        ; OR in the 4 low digits of d0 into d1
  116.       bra.s    argcnxt
  117. argcend:
  118.       move.l   d1,breakcode    ; Store the break key code
  119.       bra      nxtbyt
  120. argz:
  121.       cmp.b    #'z',d0
  122.       bne.s    argsep
  123.       st       zeroed        ; Set the 'zeroed' flag
  124.       bra      nxtbyt
  125. argsep:
  126.       cmp.b    #' ',d0        ; Accept space
  127.       beq      nxtbyt
  128.       cmp.b    #tab,d0        ; and tab
  129.       beq      nxtbyt
  130.       cmp.b    #'-',d0        ; and hyphen as separators (not strictly)
  131.       beq      nxtbyt
  132. userr:
  133.       pea.l    usemsg        ; If error in arg string show usage message
  134.       move.w   #cconws,-(sp)
  135.       trap     #gemdos
  136.       addq.l   #6,sp
  137.       move.w   #1,-(sp)
  138.       move.w   #pterm,-(sp)
  139.       trap     #gemdos        ; and terminate with error status
  140.  
  141. nxtdone:
  142.       move.w   #1,-(sp)
  143.       move.w   #iorec,-(sp)
  144.       trap     #xbios
  145.       addq.l   #4,sp
  146.       move.l   d0,iop        ; Save pointer to iorec struct
  147.       move.l   #-1,-(sp)
  148.       move.w   #$46,-(sp)
  149.       move.w   #setexc,-(sp)
  150.       trap     #bios
  151.       addq.l   #8,sp
  152.       move.l   d0,oldvec    ; Save old keyboard interrupt vector
  153.       lea.l    breakey,a0
  154.       sub.l    a0,d0
  155.       move.l   d0,diff        ; dist between start of old and new
  156.       clr.l    -(sp)
  157.       move.w   #super,-(sp)
  158.       trap     #gemdos        ; Supervisor mode
  159.       addq.l   #2,sp
  160.       move.l   d0,(sp)
  161.       lea.l    magic,a0        ; a0 points to 'magic' string in this prog
  162.       move.l   diff,d0
  163.       lea.l    (a0,d0.l),a1    ; a1 points (perhaps) to 'magic' in old
  164.       move.l   #(magicend-magic-1),d0        ; # chars in 'magic' string - 1
  165. chkmag:
  166.       cmp.b    (a0)+,(a1)+    ; Check strings for equality
  167.       dbne     d0,chkmag
  168.       beq.s    mageq        ; If old prog DID contain magic string; else:
  169. magne:
  170.       move.w   #super,-(sp)
  171.       trap     #gemdos        ; Back to user mode (sp was still on stack)
  172.       addq.l   #6,sp
  173.       clr.l    diff        ; First incarnation: will be made resident
  174.       pea.l    breakey        ; breakey will be new keyboard int. vector
  175.       move.w   #$46,-(sp)
  176.       move.w   #setexc,-(sp)
  177.       trap     #bios        ; Set it
  178.       addq.l   #8,sp
  179.       move.l   4(sp),a0        ; basepage start
  180.       move.l   #bpaglen,d0    ; base page length
  181.       add.l    textlen(a0),d0    ; + text length
  182.       add.l    datalen(a0),d0    ; + data length
  183.       add.l    bsslen(a0),d0    ; + bss length
  184.       clr.w    -(sp)        ; return value: 0 for success
  185.       move.l   d0,-(sp)        ; # bytes to keep
  186.       move.w   #ptermres,-(sp)    ; keep process
  187.       trap     #gemdos            ; stops here...
  188.  
  189. mageq:
  190.       move.w   #super,-(sp)    ; second run of this program
  191.       trap     #gemdos        ; Back to user mode
  192.       addq.l   #6,sp
  193.       move.l   diff,d0
  194.       lea.l    enabled,a0
  195.       move.b   (a0),(a0,d0.l)    ; Copy 'enabled' into old image
  196.       lea.l    zeroed,a0
  197.       move.b   (a0),(a0,d0.l)    ; Do this too for 'zeroed'
  198.       lea.l    breakcode,a0
  199.       move.l   (a0),(a0,d0.l)    ; And also for the current break char
  200.       move.w   #pterm0,-(sp)
  201.       trap     #gemdos        ; Exits here with 0 as status.
  202.  
  203. breakey:
  204. * The new interrupt routine
  205.       pea.l    breaketc        ; Return to breaketc after executing old code
  206.       move.w   sr,-(sp)        ; This is because old code ends with 'rte'
  207.       move.l   oldvec,-(sp)    ; Push old vector onto stack
  208.       rts            ; and jump to it
  209.  
  210. breaketc:
  211.       tst.b    enabled
  212.       beq      dorte        ; If not enabled do nothing
  213.  
  214.       movem.l  d0-d1/a0-a2,-(sp)
  215.       move.l   iop,a0
  216.       move.w   ibuftl(a0),d0
  217.       cmp.w    ibufhead(a0),d0
  218.       beq.s    dontbreak    ; If empty keyboard buffer do nothing
  219.       move.l   (a0),a1
  220.       move.l   (a1,d0.w),d1    ; get the last entry
  221.       and.l    #$00ff00ff,d1    ; mask only scan & ASCII part
  222.       cmp.l    breakcode,d1    ; check against break code
  223.       beq.s    normalbrk
  224.       cmp.l    hardbreak,d1    ; check against stronger break code
  225.       bne.s    dontbreak
  226.       moveq.l  #-1,d1        ; make long negative - means hard break
  227. normalbrk:
  228.       tst.b    zeroed        ; we have a break; is 'zeroed' flag set?
  229.       bne.s    dozeroed
  230.       subq.w   #4,d0        ; DECREMENT d0 with wrap
  231.       bpl.s    wrapdone
  232.       add.w    ibufsize(a0),d0
  233. wrapdone:
  234.       move.w   d0,ibuftl(a0)
  235.       bra.s    gotbreak
  236. dozeroed:
  237.       move.w   ibuftl(a0),ibufhead(a0)        ; Clear the entire buffer
  238. gotbreak:
  239.       tst.l    d1        ; hard break?
  240.       bmi.s    dobreak
  241.       btst.b   #5,20(sp)    ; test Super bit on stacked SR
  242.       bne.s    dontbreak
  243.  
  244. dobreak:
  245.       movem.l  (sp)+,d0-d1/a0-a2
  246.       move.l   #stop,2(sp)    ; Return will be to the routine 'stop'
  247.       rte
  248.  
  249. dontbreak:
  250.       movem.l  (sp)+,d0-d1/a0-a2
  251. dorte:
  252.       rte
  253.  
  254. stop:
  255.       move.w   #intrupt,-(sp)    ; Code for interrupted programs
  256.       move.w   #pterm,-(sp)
  257.       trap     #gemdos        ; and stop here
  258.  
  259. *   section  s.data
  260.  
  261. iop:        dc.l  0            ; Pointer to iorec struct
  262. breakcode:  dc.l  $002E0000        ; Defau